﻿using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

using Coding4Fun.Kinect.Wpf;
using Microsoft.Kinect;


namespace KinectWS
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public enum STATE {
            WAIT,
            DETECT,
            ACTION
        }
        KinectSensor kinect;
        EchoWebSocket ws;

        STATE state = STATE.WAIT;
        const int PORT = 8182;

        public MainWindow()
        {
            InitializeComponent();
            
            initializeKinect();
                
            ws = new EchoWebSocket(PORT);
            ws.OnMessage += ws_OnMessage;
            ws.Conect();
        }

        protected override void OnClosed(EventArgs e)
        {
            ws.Dispose();
            base.OnClosed(e);
        }

        private void initializeKinect()
        {
            try
            {
                if (KinectSensor.KinectSensors.Count == 0)
                {
                    throw new Exception("Conect the Kinect");
                }

                kinect = KinectSensor.KinectSensors[0];

                kinect.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(kinect_AllFramesReady);

                // enable Color,Depth,Skeleton
                //kinect.ColorStream.Enable();
                kinect.DepthStream.Range = DepthRange.Near; // near mode 
                kinect.DepthStream.Enable();
                kinect.SkeletonStream.Enable();

                kinect.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                Close();
            }

        }

        /// <summary>
        /// Event Handler for server
        /// </summary>
        /// <param name="msg"></param>
        void ws_OnMessage(string msg)
        {
            if (msg == "detect" || msg == "wait") return;
            this.state = STATE.ACTION;
        }
        

        /// <summary>
        /// Event Handler for kinect
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void kinect_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {

            //imageRgbCamera.Source = e.OpenColorImageFrame().ToBitmapSource();
            imageDepthCamera.Source = e.OpenDepthImageFrame().ToBitmapSource();

            ShowSkeleton(e.OpenSkeletonFrame());
        }

        private void ShowSkeleton(SkeletonFrame skeletonFrame)
        {
            boneCanvas.Children.Clear();

            if (skeletonFrame != null && skeletonFrame.SkeletonArrayLength > 0)
            {
                
                Skeleton[] skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];
                skeletonFrame.CopySkeletonDataTo(skeletonData);

                bool tracked = false;
                
                foreach (var skeleton in skeletonData)
                {
                    if (skeleton.TrackingState != SkeletonTrackingState.NotTracked)
                    {
                        // デフォルトでは反応範囲が長すぎるので、
                        if (skeleton.Position.Z < 1.7)
                        {
                            tracked = true;
                        }
                    }
                }

                if (tracked)
                {
                    // tracking...
                    switch (state)
                    {
                        case STATE.WAIT:
                            ws.SendToAllSession("detect");
                            state = STATE.DETECT;
                            break;
                        case STATE.DETECT:
                            break;
                        case STATE.ACTION:
                            break;
                    }
                }
                else
                {
                    // not tracking...
                    switch (state)
                    {
                        case STATE.WAIT:
                            break;
                        case STATE.DETECT:
                            ws.SendToAllSession("wait");
                            state = STATE.WAIT;
                            break;
                        case STATE.ACTION:
                            ws.SendToAllSession("wait");
                            state = STATE.WAIT;
                            break;
                    }
                }
                
            }
            else
            {
                debugText.Text = "nothing....";

            }

            debugText.Text = "STATE : " + this.state;
        }
        
    }
}
